package com.google.webmusic;

import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;

import com.google.webmusic.util.AppConfig;
import com.google.webmusic.util.SHA1;
/**
 * the weixin proxy api
 * @author maoanapex88@163.com Mao Anping
 *
 */
public class WeixinProxyServlet extends HttpServlet {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Logger LOGGER=Logger.getLogger(WeixinProxyServlet.class);
	
	private HttpClient httpClient = new DefaultHttpClient(); 
	private AppConfig appConfig=AppConfig.getInstance();
	
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		String token = config.getInitParameter("weixin-token");
		String appId = config.getInitParameter("weixin-appid");
		String secret = config.getInitParameter("weixin-secret");
		String target = config.getInitParameter("proxy-to");
		
		appConfig.setAppId(appId);
		appConfig.setToken(token);
		appConfig.setSecret(secret);
		appConfig.setTarget(target);
		
		if(token==null){
			LOGGER.error("Please set weixin weixin-token ");
		}
		if(target==null){
			LOGGER.error("Please set weixin proxy-to ");
		}
		if(secret==null){
			LOGGER.error("Please set weixin weixin-secret ");
		}
		if(appId==null){
			LOGGER.error("Please set weixin weixin-appId ");
		}
	}

	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		this.doPost(req, resp);
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String signature = req.getParameter("signature")+"";
        String timestamp = req.getParameter("timestamp")+"";
        String nonce = req.getParameter("nonce")+"";
        String echostr = req.getParameter("echostr")+"";
        
        Map map= req.getParameterMap();
        Iterator it = map.entrySet().iterator();
        while(it.hasNext()){
        	Entry entry=(Entry)it.next();
        	String[] values=(String[])entry.getValue();
        	StringBuilder builder=new StringBuilder();
        	for(int i=0;i<values.length;i++){
        		builder.append(values[i]).append(", ");
        	}
        	LOGGER.debug(entry.getKey()+"="+builder);
        }
        
        LOGGER.debug("===========headers==========");
        Enumeration enumeration = req.getHeaderNames();
        while(enumeration.hasMoreElements()){
        	String name=(String)enumeration.nextElement();
        	LOGGER.debug(name+"="+req.getHeader(name));
        }
        Reader reader=req.getReader();
        char[] buf=new char[512];
        int length=-1;
        while((length=reader.read(buf))!=-1){
        	LOGGER.debug(new String(buf, 0, length));
        }
        reader.close();
        
        if(authenticate(signature, timestamp, nonce)) {
        	resp.getWriter().write(echostr);
        }
        else {
        	resp.getWriter().write("You are not supposed to be here.");
        }
	}
	
	private boolean authenticate(String signature, String timestamp, String nonce){
		String[] str = { appConfig.getToken(), timestamp, nonce };
        Arrays.sort(str);
        String bigStr = str[0] + str[1] + str[2];
        String digest = SHA1.encode(bigStr);        
        return signature.equals(digest);
	}
}
